ContentCourier Deployment
-------------------------------------------------- 
The most simple ContentCourier deployment requires that you

1. Add some lines to a configuration file
2. Create a *ContentLoader* that will fetch the content for each page section
3. Create a site template


We've covered <a href="/documentation/template-system">templates</a> in a separate document</a>, so we'll concentrate on the XML Config and creating a content loader.

XML Config
-------------------------------------------------- 
Your XML config file contains two main sections.  The first is a list of valid URIs your site will respond to, and the second is a list of valid sections.  You can find out more about sections in the <a href="/documentation/template-system">template documentation</a>; for the purpose of this document you should consider them areas of your layout that will change from page to page.

If the URI portion of your config looked like this

        <uri>/documentation</uri>
        <uri>/documentation/request-flow</uri>

your site would respond to the following URIs

    http://example.com/documentation
    http://example.com/documentation/request-flow
    
Every time you add a page to your site, you'll need to modify this section of the config.  See the <a href="documentation/deployment-advanced">Advanced Deployment</a> document for suggestions on extending your deployment to dynamically create a site config.

**Important**: With the default .htaccess configuration, if apache would normally serve a file for any particular URI, ContentCourier will ignore that URI.  Put another way, if you have assets on your web server like images, CSS files, Javascript files, etc., you do not need to add a new node for each of these files.

The sections portion of the XML config will look something like this

    <sections defaultProcessor="none">
        <main    defaultContentURI="/home.php" passthrough="passthrough" processor="markdown">
            <!-- passthrough will be ignored if the following nodes have a match -->
            <map pageURI="/faq" contentURI="/faq.txt" />
        </main>
        <nav defaultContentURI="/nav.php" processor="none" />
        <header  defaultContentURI="/header.php" processor="none" />
        <sidebar defaultContentURI="/sidebar.php" processor="markdown"></sidebar>
    </sections>

This defines a site with four possible sections, named main, nav, header, and sidebar.  The various attributes and sub-nodes will be covered below.

Content Loader
-------------------------------------------------- 
The content loader is responsible for loading the content for any particular page section.  This may be the site navigation, a blog entry, an embedded Javascript widget, or any other XHTML/HTML text.

In Object Oriented terms, a Content Loader implements the abstract ContentCourierLoaderFactory class.  If that didn't make sense to you, don't worry. In fact, be grateful; it probably means you're less awkward with girls.

In simpler terms, to create a Content Loader you'll need to write a class that has, at minimum, a public method named loadContent which accepts a single argument and a public method named applyPassthroughFilter that accepts a single argument.  This class should extend the ContentCourierLoaderFactory class.  For example, to create a content loader named MyContentLoader, you'd do something like

    class ContentCourierLoaderMyContentLoader extends ContentCourierLoaderFactory{
        public function loadContent($uri){
            //your loading code goes here
        }
        
        public function applyPassthroughFilter($uri){
            return $uri;
        }        
    }

It's important your class name be prefaced with "ContentCourierLoader".  This identifies it to the System as a Content Loader.

The loadContent method will be called once for each section of your site.  The $uri parameter will contain a string with the **content URI** that needs to be loaded for that particular section.  Your code will use this content URI to load the appropriate content.  This may be mean loading the file from a disk, making a database query, or perhaps making a web service call.  This is also an ideal place for a cache-hit if you swing that way.

**Important Note #1**: Content URIs are **not** the same as the page URIs you define in the site config. The Content URI section below covers this, but we felt the need to mention this right off since it's easy to confuse them.

**Important Note #2**: Some of you are probably already thinking something along the lines of "That's one database/file-system/whatever hit" per section, I smell an inefficiency". Our Response (if you're interested)

1. You are very right
2. One way to mitigate this is to leverage a caching system, be it a simple disk hit or something sexy like memcached
3. All Content Loaders also have a reference to the main ContentCourier application ($this->contentCourierApplication from the context of your loadContent method).  You could extend the ContentCourier application to give the loader access to the information if would need to load the content for each section the first time loadContent is called, assign the content to object properties, and then consult the properties on succeeding calls.  

If the above sounds interesting, be sure to checkout the <a href="documentation/deployment-advanced">Advanced Deployment</a> document.

Content URIs
-------------------------------------------------- 
Still with us?  Good.  You're probably wondering where Content URIs come from.  There are three possible sources.

First, each section has a defaultContentURI attribute. 

    <nav defaultContentURI="/nav.php" processor="none" />
    
Lacking another source, the value of the defaultContentURI will be passed to loadContent method.  This makes a lot of sense for sections of the page that don't change (like a footer, or the site navigation).

There's a second, optional, boolean attribute for each section named passthrough

    <main defaultContentURI="/home.php" passthrough="passthrough" processor="markdown">

When a passthrough attribute is set, each content URI for a section will be **based on** the page URI.  Before being passed off the loadContent method, the page URI will be passed into the applyPassthroughFilter method of your ContentLoader.

Again, consider the default deployment with a request for the following page

    http://example.com/some/page
    
The page URI here is /some/page.  This URI is passed to the applyPasstheoughFilter method

        public function applyPassthroughFilter($uri){
            return $uri.'.php';
        }

Which gives us a content URI of /some/page.php.  This is the content URI that's passed into the loadContent method.

Finally, each section can have a specific content URI assigned to it for each page URI by using the &lt;map&gt; node.  Consider the following configuration and requests

    <main    defaultContentURI="/home.php" passthrough="passthrough">        
        <map pageURI="/faq" contentURI="/faq.txt" />
    </main>

    http://example.com/faq
    http://example.com/some/page
    http://example.com/
    
The Page URI for the first request is "/faq". This makes "/faq.txt" the content URI passed to loadContent.

The Page URI for the second request is "/some/page".  This has no &lt;map&gt; match.  Therefore, the passthrough filter is applied, and our content URI is "/some/page.php".

The Page URI for the final request is "/".  This is the root page (home page, landing page, main portal, etc.) of the site.  By definition, if there is no &lt;map&gt; match for "/", ContentCourier uses the default Content URIs. 

Processors
-------------------------------------------------- 
You use Content Processors to perform transformations on a loaded piece of content. Each section may have multiple processors attached.   You can find in more deatils in the <a href="/documentation/content-processor">Content Processor</a> document.

Specifying your Deployment
-------------------------------------------------- 
If you look at the index.php file, you'll see the following line

    $cds = ContentCourierFactory::getInstance('default','FileSystem','XML',$options);
    
This line instantiates our application.  We're interested in the second argument.  Pass in the name of your Content Loader and it will be used instead of the of the default (FileSystem).    

Wrap-up
-------------------------------------------------- 
So that's deployment, although we've only scratched the surface of what's possible.  Checkout the <a href="/documentation/deployment-advanced">Advanced Deployment</a> document for an overview of what else is possible


